/**
 * @file Circle.as
 *  3D圆圈排列图片显示类
 * @author db0@qq.com
 * @version 1.0.1
 * @date 2017-10-28
 */
package zhuhai
{
	import flash.display.DisplayObject;
	import flash.display.BitmapData;
	import flash.display.Bitmap;
	import flash.display.Sprite;
	import flash.geom.*;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.filters.GlowFilter;
	
	public class Circle extends Sprite
	{
		private var r:int;
		private var urlArr:Array;
		
		/**
		 * urlArr 图片URL数组
		 * _r	圈半径
		 * num	半圈显示的图片数量(图片总数2*num+1,第一张图居前面中间位置)
		 */
		public function Circle(urlArr:Array, _r:int = 0, num:int = 2)
		{
			if (_r == 0)
				_r = Main.stageWidth / 3;
			r = _r;
			
			x = Main.stageWidth / 2;
			y = Main.stageHeight / 2;
			z = 0;
			
			maxPhotos = num;
			this.urlArr = urlArr;
			
			//添加图片到容器
			if (urlArr && urlArr.length > 0)
			{
				addItem(urlArr[0], true);
				var i:int = 0;
				while (i < num)
				{
					var h:int = i + 1;
					while (h >= urlArr.length)
						h -= urlArr.length;
					addItem(urlArr[h], true);
					h = -i - 1;
					while (h < 0)
						h += urlArr.length;
					addItem(urlArr[h], false);
					++i;
				}
			}
			
			index = 0;
			//事件
			MyKey.main.addEventListener(MyKey.RIGHT, prev);
			MyKey.main.addEventListener(MyKey.LEFT, next);
			MyKey.main.addEventListener(MyKey.CLICK, quit);
			addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event):void
		{//设置当前容器的3D视口
			removeEventListener(Event.ADDED_TO_STAGE, init);
			root.transform.perspectiveProjection.fieldOfView = 20;
			root.transform.perspectiveProjection.focalLength = r * 2;
			root.transform.perspectiveProjection.projectionCenter = new Point(Main.stageWidth / 2, Main.stageHeight * .5 + r * .08);
			parent.rotationX = 0;
		}
		
		private var index:int = 0;//当前图片在数组中的序号
		
		private function next(e:Event):void
		{//显示下一张图
			if (stage == null || !visible)
				return;
			++index;
			if (index >= urlArr.length)
				index = 0;
			
			MyKey.main.removeEventListener(MyKey.RIGHT, prev);
			MyKey.main.removeEventListener(MyKey.LEFT, next);
			
			var _rotationY:Number = rotationY;
			rotationY += eachAngle * 180 / Math.PI;
			TweenLite.killTweensOf(this, true);
			TweenLite.from(this, .3, {rotationY: _rotationY, onComplete: onComplete});
			
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			
			addItem(urlArr[index], true);
		}
		
		private function prev(e:Event):void
		{//显示上一张图
			if (stage == null || !visible)
				return;
			
			MyKey.main.removeEventListener(MyKey.RIGHT, prev);
			MyKey.main.removeEventListener(MyKey.LEFT, next);
			
			--index;
			if (index < 0)
				index = urlArr.length - 1;
			
			var _rotationY:Number = rotationY;
			rotationY -= eachAngle * 180 / Math.PI;
			
			TweenLite.killTweensOf(this, true);
			TweenLite.from(this, .3, {rotationY: _rotationY, onComplete: onComplete});
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			
			addItem(urlArr[index], false);
		}
		
		private function onComplete(e:Event = null):void
		{//动作完成
			removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			
			MyKey.main.addEventListener(MyKey.RIGHT, prev);
			MyKey.main.addEventListener(MyKey.LEFT, next);
		}
		
		private var maxPhotos:int = 1;//半圈图片数量
		private var headAngle:Number = 0;//list头部图片旋转角度
		private var railAngle:Number = 0;//list尾部图片旋转角度
		
		private function get eachAngle():Number
		{//图片间夹角大小
			return (Math.PI * 2 / (maxPhotos * 2 + 1));
		}
		
		private var list:Array;//保存显示的图片的双向列表
		
		/**
		 * url:	图片地址
		 * _head:	true将图片添加在list列表的头部，false添加到尾部
		 * 将图片添加到舞台，
		 */
		private function addItem(url:String, _head:Boolean = true):void
		{
			var mc:PhotoLoader = new PhotoLoader(url);
			addChild(mc);
			if (list == null)
			{//第一张图初始化列表，及角度
				list = new Array;
				headAngle = -Math.PI / 2;
				railAngle = headAngle + eachAngle;
			}
			
			if (list.length < maxPhotos * 2 + 1)
			{
				if (_head)
				{//添加到头部
					list.push(mc);
					mc.x = -r * Math.cos(headAngle);
					mc.z = r * Math.sin(headAngle);
					headAngle -= eachAngle;
				}
				else
				{//添加到尾部
					list.unshift(mc);
					mc.x = -r * Math.cos(railAngle);
					mc.z = r * Math.sin(railAngle);
					railAngle += eachAngle;
				}
			}
			else
			{
				var old:PhotoLoader;
				if (_head)
				{//添加到头部,删除尾部图片
					list.push(mc);
					old = list.shift();
				}
				else
				{//添加到尾部,删除头部图片
					list.unshift(mc);
					old = list.pop();
				}
				mc.x = old.x;
				mc.y = old.y;
				mc.z = old.z;
				removeChild(old);
			}
			sortItems();
		}
		
		private function sortItems():void
		{//重新排列图片在舞台的深度及旋转角度
			var arr:Array = new Array;
			for (var i:int = 0; i < numChildren; i++)
			{
				var mc:DisplayObject = getChildAt(i);
				mc.rotationY = -rotationY;
				if (parent)
					mc.rotationX = -parent.rotationX;
				var posA:Vector3D = mc.transform.matrix3D.position;
				posA = this.transform.matrix3D.deltaTransformVector(posA);
				trace(posA.z);
				var n:Number = 1 - (r - (posA.z)) / r/2;
				mc.alpha = 1.7 - n;
				if (posA.z > -r * .95)
					mc.filters = [new BlurFilter(20*n, 20*n)];
				else
					mc.filters = [];
				arr.push(mc);
			}
			if (arr.length < 2)
				return;
			arr.sort(depthSort);
			for (i = 0; i < arr.length; i++)
			{
				addChildAt(arr[i], i);
			}
		}
		
		private function depthSort(objA:DisplayObject, objB:DisplayObject):int
		{//深度（z）比较函数
			var posA:Vector3D = objA.transform.matrix3D.position;
			posA = this.transform.matrix3D.deltaTransformVector(posA);
			var posB:Vector3D = objB.transform.matrix3D.position;
			posB = this.transform.matrix3D.deltaTransformVector(posB);
			return posB.z - posA.z;
		}
		
		private var deltaAngle:int = 0;
		
		private function onEnterFrame(event:Event):void
		{//运动补间效果时，重新图片位置和旋转角度
			if (numChildren > 1)
				sortItems();
		}
		
		private function quit(e:Event = null):void
		{//退出时清除事件
			if (stage == null || !visible)
				return;
			MyKey.main.removeEventListener(MyKey.CLICK, quit);
			MyKey.main.removeEventListener(MyKey.RIGHT, prev);
			MyKey.main.removeEventListener(MyKey.LEFT, next);
			removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
	}
}
